
namespace Pixels.ContentTypes.DataLayer
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
    using Pixels.DataLayer;
    using Pixels.Exceptions;

    internal class DataAccessLayer : IDataAccessLayer
    {
        private DbHelper helper;

        #region Constructors
        public DataAccessLayer()
        {
            helper = new CommonDbHelper();
        }
        public DataAccessLayer(string ConnectionStringName)
        {
            helper = new CommonDbHelper(ConnectionStringName);
        }
        #endregion

        #region Methods

        public IContentType ContentTypeAddEdit(IContentType objContentType, bool updateifExists)
        {
            try
            {
                IContentType _contenttype = ContentTypeFetch(objContentType.Title);

                if (updateifExists == false && _contenttype != null)
                   throw new Exception("Content Type already exists.");

                if (_contenttype == null)
                {
                    helper.ExecuteNonQuery(SqlQueryBuilder.GetInsertQuery(objContentType),CommandType.Text);
                }
                else
                {
                    objContentType.ContentTypeID = _contenttype.ContentTypeID;
                    helper.ExecuteNonQuery(SqlQueryBuilder.GetUpdateQuery(objContentType, "ContentTypeID"), CommandType.Text);
                }

                return objContentType;
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType could not be added/modified. Please Contact System Administrator");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public void ContentTypeDelete(Guid ContentTypeID)
        {
            try
            {
                helper.ExecuteNonQuery(DBConstants.ContentTypeDelete, ContentTypeID);                
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType not be deleted");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public IContentType ContentTypeFetch(Guid ContentTypeID)
        {
            ContentType objContentType = null;
            try
            {
                using (IDataReader reader = helper.ExecuteReader(DBConstants.ContentTypeFetchByListID, ContentTypeID))
                {
                    if ((reader != null) && (reader.Read()))
                    {
                        objContentType = new ContentType();

                        LoadToContentType(objContentType, reader);
                    }
                    reader.Close();
                    return objContentType;
                }
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType Detail could not be found");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public IContentType ContentTypeFetchByListID(Guid ListID)
        {
            ContentType objContentType = null;
            try
            {
                using (IDataReader reader = helper.ExecuteReader(DBConstants.ContentTypeFetchByID, ListID))
                {
                    if ((reader != null) && (reader.Read()))
                    {
                        objContentType = new ContentType();

                        LoadToContentType(objContentType, reader);
                    }
                    reader.Close();
                    return objContentType;
                }
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType Detail could not be found");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public IContentType ContentTypeFetch(string ContentType)
        {
            ContentType objContentType = null;
            try
            {
                using (IDataReader reader = helper.ExecuteReader(DBConstants.ContentTypeFetchByName, ContentType))
                {
                    if ((reader != null) && (reader.Read()))
                    {
                        objContentType = new ContentType();

                        LoadToContentType(objContentType, reader);
                    }
                    reader.Close();
                    return objContentType;
                }
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType Detail could not be found");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public IContentType ContentTypeFetchByContentTypeItemID(Guid ContentItemID)
        {
            ContentType objContentType = null;
            try
            {
                using (IDataReader reader = helper.ExecuteReader(DBConstants.ContentTypeFetchByContentTypeItemID, ContentItemID))
                {
                    if ((reader != null) && (reader.Read()))
                    {
                        objContentType = new ContentType();

                        LoadToContentType(objContentType, reader);

                    }
                    reader.Close();
                    return objContentType;
                }
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("ContentType Detail could not be found");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        public IList<IContentType> ContentTypesFetch()
        {
            IList<IContentType> ContentTypes = null;
            try
            {
                using (IDataReader reader = helper.ExecuteReader(DBConstants.ContentTypesFetch, CommandType.Text))
                {
                    if ((reader != null))
                    {
                        ContentTypes = new List<IContentType>();
                        while (reader.Read())
                        {
                            ContentType objContentType = new ContentType();

                            LoadToContentType(objContentType, reader);

                            ContentTypes.Add(objContentType);
                        }
                    }
                    reader.Close();
                    return ContentTypes;
                }
            }
            catch (DbException DbEx)
            {
                bool rethrow = ExceptionPolicy.HandleException(DbEx, "Data Layer Policy");
                throw new DLWrappedException("Error in Fetching ContentType Details.");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        private void LoadToContentType(ContentType objContentType, IDataReader reader)
        {
            objContentType.ContentTypeID = Guid.Parse(reader["ContentTypeID"].ToString());
            objContentType.Title = reader["Title"].ToString();
            objContentType.Description = reader["Description"].ToString();
            DateTime createdDate, modifiedDate;
            DateTime.TryParse(reader["CreatedDate"].ToString(), out createdDate);
            DateTime.TryParse(reader["ModifiedDate"].ToString(), out modifiedDate);
            objContentType.CreatedDate = createdDate;
            objContentType.ModifiedDate = modifiedDate;
            Guid baseContentTypeID;
            Guid.TryParse(reader["ContentTypeID"] == null ? "" : reader["ContentTypeID"].ToString(), out baseContentTypeID);
            objContentType.BaseContentTypeID = baseContentTypeID;
        }
        #endregion        
    }
}
